﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml;

using ns_User;
using ns_SecurityManage;
using ns_DatabaseAccess;
using ns_FilesManage;
using ns_SessionManage;
using ns_FriendsList;
using ns_CacheManage;
using ns_MsgRecords;
using ns_AppManage;
using ns_Utility;
using ns_Profile;
using ns_SystemInfoManage;
using ns_SystemConst;
using ns_ImageManage;

namespace ns_ServerOperation
{
    public static class s_c_GetOperation //获得服务器上的操作接口
    {
        public static i_ServerOperation ServerOperation
        {
            get { return _ServerOperation; }
        }
        private static c_ServerOperation _ServerOperation = new c_ServerOperation();
    }
    public interface i_ServerOperation 
    {
        //用户注册
         Boolean Register(String name, String password, String question, String answer, String sex, String address, String email, String phone, String signWords);
        //Boolean Register(String name, String password, String question, String answer, String sex, String address, String email, String phone);
        //Boolean Register(String name, String password, String question, String answer);
        Boolean Register(String name, String password);

        Boolean Login(String name, String password); //登录
        void Exit();
        Boolean IsCurrentUserLogin(); //检查是否登录
        Boolean UpdateTime(); //将和时间有关的最新数据存入数据库
        Boolean IsNameExist(String name);//用户名是否存在
        //Boolean Exit(String name); //安全退出

       // Boolean ProfileEdit();
        String GetProfile(String Name);
        Boolean SetProfile(String Sex, String Address, String Email, String Phone, String SighWords);

        Boolean SendMSG( String toName, String fromIP, String content);//发送聊天信息，实际是将信息格式化，一式两份，一份放到Cache里（如果在线），另外一份放在发送聊天记录的文件里
        //Boolean AddFriends(String name, String friendName, String friendType); //将friendName加到好友列表中,friendType为用户自定义的好友类型，默认为“我的好友”
        String GetMSG(); //获取当前用户的及时聊天信息缓存，返回的是xml格式的字符串
        String GetMSGRecord(String name);//获取与某人聊天记录
        String GetFriendsList(); //获取好友列表，返回的是xml格式的字符串
        Int32 GetSystemInfoNumber();//系统消息数
        String GetSystemInfoXml(); //系统消息内容
        Boolean AddFriendRequest(String friendName, String friendType, String regMsg);//添加好友请求
        Boolean AddFriendPass(String friendName, String friendType,String MyType);//添加好友请求确认
        Boolean DelFriend(String friendName);//删除好友
        Boolean LoadMsgNotGotToCache();
        Boolean UploadHeadImg(HttpPostedFile HeadImgFile);//头像上传
        Boolean UpdateFriendsStates(); //更新好友列表中的状态
        String contentFilter(String content);//内容过滤器，主要是内容格式规范化，防止后续的xml文件操作失败（javascript和c#的dom存在很多解释差异），另外可以将一些敏感字眼“和谐”掉……
    }
    public class c_ServerOperation : i_ServerOperation
    {     
        public Boolean Register(String name, String password)
        {
            c_User user = new c_User();
            if (c_DBA.SqlDataAccess.IsUserExist(name)) return false;
            user.Name = name;
            user.Address = "unknow";
            user.Email = "unknow";
            user.HashedAnswer = ns_SecurityManage.c_Hash.Md5("unknow");
            user.HashedPassword = ns_SecurityManage.c_Hash.Md5(password);
            user.ID = c_DBA.SqlDataAccess.NewID();
            user.LastLogTime = DateTime.Now;
            user.OnlineTime = TimeSpan.FromMilliseconds(0);
            user.LeaveTime = DateTime.Now;
            user.LogTimes = 0;
            user.Phone = "";
            user.Points = 12;
            user.Question = "unknow";
            user.RegTime = DateTime.Now;
            user.Roles = 32;
            user.Sex = "男";
            user.SighWords = "一起和谐";

            String Path = "";
            Path = s_c_FilesManage.FilesManage.NewFriendsListXml(user.Name);
            if (Path == null)
            {
                c_DBA.SqlDataAccess.DeleteUser(user.Name);
                return false;
            }
            user.FriendsListXmlPath =Path ;

            Path = s_c_FilesManage.FilesManage.NewMsgGotRecordsXml(user.Name);
            if (Path == null)
            {
                c_DBA.SqlDataAccess.DeleteUser(user.Name);
                return false;
            }
            user.MsgGotRecordsXmlPath = Path;

            Path = s_c_FilesManage.FilesManage.NewMsgSentRecordsXml(user.Name);
            if (Path == null)
            {
                c_DBA.SqlDataAccess.DeleteUser(user.Name);
                return false;
            }
            user.MsgSentRecordsXmlPath = Path;

            Path = s_c_FilesManage.FilesManage.NewImgHeadPath(user.Name);
            if (Path == null)
            {
                c_DBA.SqlDataAccess.DeleteUser(user.Name);
                return false;
            }
            user.ImgHeadPath = Path;

            Path = s_c_FilesManage.FilesManage.ImgHeadUrl(user.Name);
            if (Path == null)
            {
                c_DBA.SqlDataAccess.DeleteUser(user.Name);
                return false;
            }
            user.ImgHeadUrl = Path;

            if (!c_DBA.SqlDataAccess.AddUser(user)) return false; 
            else return true;
        }
        public Boolean Register(String name, String password, String question, String answer, String sex, String address, String email, String phone, String signWords)
        {
            c_User user = new c_User();
            if (c_DBA.SqlDataAccess.IsUserExist(name)) return false;
            if (password == "") return false;
            user.Name = name;

            if (question == null || question == "") { user.Question = "unknow"; }
            else{user.Question = question;}

            if (answer == null || answer == "") { user.HashedAnswer = ns_SecurityManage.c_Hash.Md5("unknow"); }
            else{user.HashedAnswer = ns_SecurityManage.c_Hash.Md5(answer);}
            if (sex == null || sex == "") { user.Sex = "男"; }
            else{user.Sex = sex;}
            if (sex == null || sex == "") { user.Address = "unknow"; }
            else{user.Address = sex;}
            if (email == null || email == "") { user.Email = "unknow"; }
            else{user.Email = email;}
            if (phone == null || phone == "") { user.Phone = "unknow"; }
            else{user.Phone = phone;}
            if (signWords == null || signWords == "") { user.SighWords = "一起和谐"; }
            else{user.SighWords = signWords;}
            user.HashedPassword = ns_SecurityManage.c_Hash.Md5(password);
            user.ID = c_DBA.SqlDataAccess.NewID();
            user.LastLogTime = DateTime.Now;
            user.OnlineTime = TimeSpan.FromMilliseconds(0);
            user.LeaveTime = DateTime.Now;
            user.LogTimes = 0;
            user.Points = 12;
            user.RegTime = DateTime.Now;
            user.Roles = 32;
            
            
            String Path = "";
            Path = s_c_FilesManage.FilesManage.NewFriendsListXml(user.Name);
            if (Path == null)
            {
                c_DBA.SqlDataAccess.DeleteUser(user.Name);
                return false;
            }
            user.FriendsListXmlPath = Path;

            Path = s_c_FilesManage.FilesManage.NewMsgGotRecordsXml(user.Name);
            if (Path == null)
            {
                c_DBA.SqlDataAccess.DeleteUser(user.Name);
                return false;
            }
            user.MsgGotRecordsXmlPath = Path;

            Path = s_c_FilesManage.FilesManage.NewMsgSentRecordsXml(user.Name);
            if (Path == null)
            {
                c_DBA.SqlDataAccess.DeleteUser(user.Name);
                return false;
            }
            user.MsgSentRecordsXmlPath = Path;

            Path = s_c_FilesManage.FilesManage.NewImgHeadPath(user.Name);
            if (Path == null)
            {
                c_DBA.SqlDataAccess.DeleteUser(user.Name);
                return false;
            }
            user.ImgHeadPath = Path;

            Path = s_c_FilesManage.FilesManage.ImgHeadUrl(user.Name);
            if (Path == null)
            {
                c_DBA.SqlDataAccess.DeleteUser(user.Name);
                return false;
            }
            user.ImgHeadUrl = Path;

            Path = s_c_FilesManage.FilesManage.NewSystemInfoXml(user.Name);
            if (Path == null)
            {
                c_DBA.SqlDataAccess.DeleteUser(user.Name);
                return false;
            }
            user.SystemInfoXmlPath = Path;

            if (!c_DBA.SqlDataAccess.AddUser(user)) return false;
            else return true;
        }
        public Boolean Login(String name, String password)
        {
            c_User user = c_DBA.SqlDataAccess.GetUser(name);
            if (user == null) return false;
            if (!s_c_Utility.ByteArrayCmp(user.HashedPassword, c_Hash.Md5(password))) return false;
            c_FriendsListXml flx = new c_FriendsListXml(user.FriendsListXmlPath);
            user.FriendsListCache = flx.FriendsListXml;
            user.LogTimes++;
            c_SessionManage.SaveCurrentUser(user);
            c_CacheManage.NewMsgCache(user.Name);//消息缓冲区
            LoadMsgNotGotToCache();
            UpdateFriendsHeadUrl();
            user.LastLogTime = DateTime.Now;
            user.LeaveTime = DateTime.Now;
            return true;
        }
        public void Exit()
        {
            if (IsCurrentUserLogin())
            {
            c_DBA.SqlDataAccess.UpdateUser(c_SessionManage.GetCurrentUser());
            c_CacheManage.DelMsgCahce(c_SessionManage.GetCurrentUser().Name); //删除缓冲区
            c_SessionManage.DelCurrentUser();
            }
        }
        public Boolean IsCurrentUserLogin()
        {
            if (c_SessionManage.GetCurrentUser() == null)
            {
                return false;
            }
            else
            {
                UpdateTime();
                return true;
            }
        }
        public String GetFriendsList()
        {
            UpdateFriendsStates();
            c_User user = c_SessionManage.GetCurrentUser();
            return user.FriendsListCache;
        }
        public Int32 GetSystemInfoNumber()
        {
            c_SystemInfoXml six = new c_SystemInfoXml(c_SessionManage.GetCurrentUser().SystemInfoXmlPath);
            return six.GetSystemInfoNumber(c_SessionManage.GetCurrentUser().Name);
        }
        public String GetSystemInfoXml()
        {
            c_SystemInfoXml six = new c_SystemInfoXml(c_SessionManage.GetCurrentUser().SystemInfoXmlPath);
            String temp = six.GetSystemInfoXml(c_SessionManage.GetCurrentUser().Name);
            six.DelAllInfo();
            six.SaveSystemInfoXml(c_SessionManage.GetCurrentUser().SystemInfoXmlPath);
            return temp;
        }
        public Boolean AddFriendRequest(String friendName, String friendType ,String regMsg)
        {
            String path = c_DBA.SqlDataAccess.GetUser(friendName).SystemInfoXmlPath;
            c_SystemInfoXml six = new c_SystemInfoXml(path);
            six.AddFriendRequestInfo(c_SessionManage.GetCurrentUser().Name, friendName, friendType, regMsg);
            if (six.SaveSystemInfoXml(path))
            { return true; }
            else return false;
        }
        public Boolean AddFriendPass(String friendName, String friendType ,String MyType)
        {
            return AddFriend(c_SessionManage.GetCurrentUser().Name,MyType,friendName, friendType);
        }
        public Boolean AddFriend(String MyName , String MyType ,String friendName, String friendType)
        {
            if (c_DBA.SqlDataAccess.GetUser(friendName) == null) return false;
            c_User user = c_SessionManage.GetCurrentUser();
            if (user == null||user.Name==friendName ) return false;
            c_FriendsListXml flx = new c_FriendsListXml(user.FriendsListCache, true);
            if (!flx.IsFriendExist(friendName))
            {
                if (flx.AddFriend(friendName, friendType))
                {
                    user.FriendsListCache = flx.FriendsListXml;
                    c_SessionManage.SaveCurrentUser(user);
                    if (!flx.SaveFriendsListXml(user.FriendsListXmlPath)) return false;
                }
                else return false;
            }
            c_User userFriend = c_DBA.SqlDataAccess.GetUser(friendName);
            flx = new c_FriendsListXml(userFriend.FriendsListXmlPath);
            if (!flx.IsFriendExist(user.Name))
            {
                if (flx.AddFriend(user.Name, MyType))
                {
                    if (!flx.SaveFriendsListXml(userFriend.FriendsListXmlPath)) return false;
                    return true;
                }
                else return false;
            }
            return false;
        }
        public Boolean DelFriend(String friendName)
        {
            if (c_DBA.SqlDataAccess.GetUser(friendName) == null) return false;
            c_User user = c_SessionManage.GetCurrentUser();
            if (user == null) return false;
            c_FriendsListXml flx = new c_FriendsListXml(user.FriendsListCache, true);
            if (!flx.IsFriendExist(friendName)) return true;//不是好友
            if (flx.RemoveFriend(friendName))
            {
                user.FriendsListCache = flx.FriendsListXml;
                if (!flx.SaveFriendsListXml(user.FriendsListXmlPath)) return false;
                return true;
            }
            else return false;
        }
        public String GetMSG()
        {
            return c_CacheManage.GetMsgCache(c_SessionManage.GetCurrentUser().Name);
        }
        public String GetMSGRecord(String name)
        { 
            c_MsgRecordsXml msrx = new c_MsgRecordsXml(c_SessionManage.GetCurrentUser().MsgSentRecordsXmlPath);
            c_MsgRecordsXml mgrx = new c_MsgRecordsXml(c_SessionManage.GetCurrentUser().MsgGotRecordsXmlPath);
            String To = msrx.GetRecordsXmlByToName(name);
            String From = mgrx.GetRecordsXmlByFromName(name);
            c_MsgRecordsXml msrxTo;
            c_MsgRecordsXml mgrxForm;
            if (To == null && From == null) return null;
            if (To == null) {
                 mgrxForm = new c_MsgRecordsXml(From, true);
                return mgrxForm.MsgRecordsXml;
            }
            if (From == null) {
                msrxTo = new c_MsgRecordsXml(To, true);
                return msrxTo.MsgRecordsXml;
            }
             msrxTo = new c_MsgRecordsXml(To, true);
             mgrxForm = new c_MsgRecordsXml(From, true);
             c_MsgRecordsXml temp = new c_MsgRecordsXml(msrxTo.AddMsgRecords(mgrxForm),true);
             return temp.OrderRecordsXmlByDateTime();
        }
        public Boolean SendMSG(String toName ,String fromIP, String content)
        {
            try
            {
                content =contentFilter(content);
                c_User user = c_SessionManage.GetCurrentUser();
                if (c_CacheManage.IsCacheExist(toName))//用户在线，放到缓冲区
                {
                    c_MsgRecordsXml mrxCache = new c_MsgRecordsXml();
                    mrxCache.AddMsgRecord(user.Name, toName, fromIP, DateTime.Now.ToString(), content);
                    c_CacheManage.SendMsg(toName, mrxCache.MsgRecordsXml);
                }
                //与此同时，放到toName的接收文件中

                c_User toUser = c_DBA.SqlDataAccess.GetUser(toName);
                c_MsgRecordsXml mrx = new c_MsgRecordsXml(toUser.MsgGotRecordsXmlPath);
                mrx.AddMsgRecord(user.Name, toName, fromIP, DateTime.Now.ToString(), content);
                mrx.SaveMsgRecordsXml(toUser.MsgGotRecordsXmlPath);
               
                //保存聊天记录
                c_MsgRecordsXml mrxXml = new c_MsgRecordsXml(user.MsgSentRecordsXmlPath);
                mrxXml.AddMsgRecord(user.Name, toName, fromIP, DateTime.Now.ToString(), content);
                mrxXml.SaveMsgRecordsXml(user.MsgSentRecordsXmlPath);
                return true;
            }
            catch (Exception e)
            {
                return false;
            }
        }
        public Boolean LoadMsgNotGotToCache()
        {
            c_User user = c_SessionManage.GetCurrentUser();
            if (user == null) return false;
            c_MsgRecordsXml mrx = new c_MsgRecordsXml (user.MsgGotRecordsXmlPath);
            String MsgNotGot = mrx.GetRecordsXmlByDateTime(user.LeaveTime, DateTime.Now);
            if(MsgNotGot != null )c_CacheManage.SendMsg(user.Name,MsgNotGot);
            return true;
        }
        public Boolean UpdateTime()
        {
            try {
                c_User user = c_SessionManage.GetCurrentUser();
                DateTime temp = user.LeaveTime;
                user.LeaveTime = DateTime.Now;
                user.OnlineTime += user.LeaveTime - temp;
                c_SessionManage.SaveCurrentUser(user);
                c_DBA.SqlDataAccess.UpdateUser(user);
                return true;
            }
            catch (Exception e)
            {
                return false;
            }
        }
        public Boolean UpdateFriendsStates()
        {
            try
            {
                c_FriendsListXml flx = new c_FriendsListXml(c_SessionManage.GetCurrentUser().FriendsListXmlPath);
                //更新操作
                for (int i = 0; i < flx.CountFriends(); i++)
                {
                    if (c_CacheManage.IsCacheExist(flx.GetFriendName(i))) flx.SetFriendState(i, flx.OnLine);
                    else flx.SetFriendState(i, flx.OffLine);
                }
                c_SessionManage.GetCurrentUser().FriendsListCache = flx.FriendsListXml;
                return true;
            }
            catch (Exception e)
            { return false; }
        }
        public Boolean UpdateFriendsHeadUrl()
        {
            try
            {
                c_FriendsListXml flx = new c_FriendsListXml(c_SessionManage.GetCurrentUser().FriendsListCache, true);
                //更新操作
                for (int i = 0; i < flx.CountFriends(); i++)
                {
                    String name = flx.GetFriendName(i);
                    c_User user =c_DBA.SqlDataAccess.GetUser(name);
                    flx.SetFriendHeadUrl(user.Name,user.ImgHeadUrl);
                }
                c_SessionManage.GetCurrentUser().FriendsListCache = flx.FriendsListXml;
                c_DBA.SqlDataAccess.UpdateUser(c_SessionManage.GetCurrentUser());
                return true;
            }
            catch (Exception e)
            { return false; }
        }
        public String contentFilter(String content)
        {
            String temp = null;
            content = content.Replace("&nbsp;", " ");
            temp += content.Substring(0,content.IndexOf('>',0)+1);
            for (Int32 i = content.IndexOf('>', 0) + 1; i < content.Length-6; )
            {
                temp += content.Substring(i, content.IndexOf('<', i) - i );

                if ( temp.Substring(temp.Length - 5, 5) != "<br/>")
                {
                    if (content.Substring(content.IndexOf('<', i), content.IndexOf('>', i) - content.IndexOf('<', i)).Contains("/")
                        || content.Substring(content.IndexOf('<', i), content.IndexOf('>', i) - content.IndexOf('<', i)).Contains("BR")
                        || content.Substring(content.IndexOf('<', i), content.IndexOf('>', i) - content.IndexOf('<', i)).Contains("br"))
                    temp += "<br/>"; //换行
                }
                i = content.IndexOf('>', i) + 1;
            }
            temp += "</DIV>";
            return temp;
        }
        public String GetProfile(String Name)
        {
            if (Name == "" || Name == null) return null;
            if (Name == c_SessionManage.GetCurrentUser().Name)
            {
                return s_c_Profile.GetMyProfile();
            }
            else
            {
                return s_c_Profile.GetProfile(Name);
            }
        }
        public Boolean SetProfile(String Sex, String Address, String Email, String Phone, String SighWords)
        {
            if (Sex == null || Address == null || Email == null || Phone == null || SighWords == null) { return false; }
            if (Sex == "") Sex = "男";
            if (Address == "" ) Address = "未知";
            if (Email == "" ) Email = "未知";
            if (Phone == "" ) Phone = "未知";
            if (SighWords == "") SighWords = "未知";
            if (s_c_Profile.SetMyProfile(Sex, Address, Email, Phone, SighWords)) return true;
            else return false;
        }
        public Boolean UploadHeadImg(HttpPostedFile HeadImgFile)
        {
            string fullFileName = HeadImgFile.FileName;
            string fileName = fullFileName.Substring(fullFileName.LastIndexOf(@"\") + 1);
            string typeName = (fullFileName.Substring(fullFileName.LastIndexOf(".") + 1)).ToLower();
            if (typeName == "jpg" || typeName == "bmp" || typeName == "gif" || typeName == "jpeg")
            {
                String TempFileName = c_Const.WEBSITE_PATH + "/Resource/TempImages/temp_" + fileName;
                String DestFileName = c_Const.WEBSITE_PATH + "/Resource/TempImages/Dest_" + fileName;
                HeadImgFile.SaveAs(TempFileName);
                c_Image.ImageFormal(TempFileName, DestFileName, 30, 26);
                s_c_FilesManage.FilesManage.UpdateImgHeadPath(c_SessionManage.GetCurrentUser().Name, DestFileName);
                s_c_FilesManage.FilesManage.DeleteFile(TempFileName);
                s_c_FilesManage.FilesManage.DeleteFile(DestFileName);
                return true;
            }
            else return false;
        }
        public Boolean IsNameExist(String name)
        {
            return c_DBA.SqlDataAccess.IsUserExist(name);
        }
    }

}
